
package com.hlkj.pay.app.merchant.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.pay.dto.merchant.MerchantInfoRegisterDto;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.IAgentInfoAppService;
import com.hlkj.pay.app.merchant.IMerchantInfoAppService;
import com.hlkj.pay.common.AdminUserResultCode;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.admin.AdminUserDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.AgentInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantConfigDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.service.admin.IAdminUserService;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.merchant.IAgentService;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.service.merchant.impl.MerchantHandler;
import com.hlkj.pay.vo.merchant.req.agent.AgentInfoAddReq;
import com.hlkj.pay.vo.merchant.req.agent.AgentInfoUpdateReq;
import com.hlkj.pay.vo.merchant.req.MerchantConfigReq;

import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * @author HlpayTeam
 * @date 2024/09/12 11:40
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AgentInfoAppServiceImpl implements IAgentInfoAppService {

    private final IMerchantService merchantService;

    private final IAdminUserService userService;

    private final IBusinessLogService businessLogService;

    private final IAgentService agentService;

    private final IMerchantInfoAppService merchantInfoAppService;

    private final MerchantHandler merchantHandler;

    private final IMerchantApplicationService merchantApplicationService;

    @Override
    @Transactional
    public CommonResult<String> addAgentInfo(AgentInfoAddReq agentInfoAddReq) {
        try {
            AdminUserDto adminUserDto = userService.queryUserByPhone(agentInfoAddReq.getLegalPhone(), CommonEnum.SYS_TYPE.AGENT.getCode());
            if (adminUserDto != null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_EXIST);
            }
            adminUserDto = userService.queryUserByAccount(agentInfoAddReq.getAccount(), CommonEnum.SYS_TYPE.AGENT.getCode());
            if (adminUserDto != null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_EXIST);
            }
        }
        catch (Exception e) {
            return CommonResult.error(CommonResultCode.DATA_ENCRYPT_ERROR);
        }
        // 2 商户信息生成（包含应用id）
        MerchantInfoRegisterDto merchantInfoRegisterDto = BeanUtil.copyProperties(agentInfoAddReq, MerchantInfoRegisterDto.class);
        merchantInfoRegisterDto.setSysType(CommonEnum.SYS_TYPE.AGENT);
        merchantInfoRegisterDto.setPhone(agentInfoAddReq.getLegalPhone());
        merchantInfoRegisterDto.setSnType(MerchantEnum.MERCHANT_SN_TYPE.AGENT.getCode());
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(agentInfoAddReq.getPasswordType())) {
            merchantInfoRegisterDto.setPwd(agentInfoAddReq.getPassword());
        }
        CommonResult<String> commonResult = merchantHandler.register(merchantInfoRegisterDto, agentInfoAddReq.getProviderCodeList(), agentInfoAddReq.getChannelCodeList());
        if (!commonResult.isSuccess()) {
            return commonResult;
        }
        AgentInfoDO agentInfoDO = BeanUtil.copyProperties(agentInfoAddReq, AgentInfoDO.class);
        agentInfoDO.setSn(commonResult.getData());
        agentService.addAgentInfo(agentInfoDO);
        return commonResult;
    }

    @Override
    @Transactional
    public CommonResult<Void> updateAgent(AgentInfoUpdateReq agentInfoUpdateReq) {
        log.info("updateMerchantInfo agentInfoUpdateReq:{}", JsonUtils.toJsonString(agentInfoUpdateReq));
        try {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(agentInfoUpdateReq.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO updateMerchantInfoDO = BeanUtil.copyProperties(agentInfoUpdateReq, MerchantInfoDO.class);
            merchantService.updateMerchantBySn(updateMerchantInfoDO);

            AgentInfoDO agentInfoDO = BeanUtil.copyProperties(agentInfoUpdateReq, AgentInfoDO.class);
            agentInfoDO.setSn(agentInfoUpdateReq.getSn());
            agentService.updateAgentInfoBySn(agentInfoDO);
            // 修改配置
            if (!CollectionUtils.isEmpty(agentInfoUpdateReq.getChannelCodeList()) && !CollectionUtils.isEmpty(agentInfoUpdateReq.getProviderCodeList())) {
                MerchantConfigReq merchantConfigReq = new MerchantConfigReq();
                merchantConfigReq.setSn(agentInfoUpdateReq.getSn());
                merchantConfigReq.setProviderCodeList(agentInfoUpdateReq.getProviderCodeList());
                merchantConfigReq.setChannelCodeList(agentInfoUpdateReq.getChannelCodeList());
                merchantInfoAppService.saveConfig(merchantConfigReq);
            }
            businessChangeLog(merchantInfoDO, updateMerchantInfoDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delAgent(String sn) {
        log.info("delMerchant sn:{}", sn);
        try {
            if (!StringUtils.hasText(sn)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            CommonResult<Void> commonResult = merchantInfoAppService.delMerchant(sn);
            if (!commonResult.isSuccess()) {
                return commonResult;
            }
            agentService.delAgentInfo(sn);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    /**
     * log object
     *
     * @param beforeMerchantInfo
     * @param afterPayMerchantInfo
     * @return
     */
    void businessChangeLog(MerchantInfoDO beforeMerchantInfo, MerchantInfoDO afterPayMerchantInfo) {
        businessLogService.addBusinessChangeLog(beforeMerchantInfo.getSn(), MerchantEnum.CHANGE_LOG_TYPE.MERCHANT_INFO.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.MERCHANT,
                beforeMerchantInfo, afterPayMerchantInfo);
    }

    /**
     * log object
     *
     * @param beforeMerchantInfo
     * @param afterPayMerchantInfo
     * @return
     */
    void businessChangeLog(MerchantConfigDO beforeMerchantInfo, MerchantConfigDO afterPayMerchantInfo) {
        businessLogService.addBusinessChangeLog(beforeMerchantInfo.getSn(), MerchantEnum.CHANGE_LOG_TYPE.MERCHANT_CONFIG.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.MERCHANT,
                beforeMerchantInfo, afterPayMerchantInfo);
    }

}
